package com.party.admin.web.controller.analysis;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.party.admin.biz.analysis.StatisticalFunnelBizService;
import com.party.admin.web.dto.AjaxResult;
import com.party.admin.web.dto.input.common.CommonInput;
import com.party.admin.web.dto.output.analysis.StatisticalFunnelOutput;
import com.party.common.paging.Page;
import com.party.common.utils.StringUtils;
import com.party.core.model.analysis.StatisticsEvent;
import com.party.core.model.analysis.StatisticsFunnel;
import com.party.core.model.analysis.StatisticsFunnelFlow;
import com.party.core.model.member.MemberGroup;
import com.party.core.service.analysis.IStatisticsEventService;
import com.party.core.service.analysis.IStatisticsFunnelCountService;
import com.party.core.service.analysis.IStatisticsFunnelFlowService;
import com.party.core.service.analysis.IStatisticsFunnelService;
import com.party.core.service.member.IMemberGroupService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * 漏斗控制器
 *
 * @author yifeng
 * @date 2018/8/2 0002
 * @time 上午 10:39
 */
@Controller
@RequestMapping("analysis/funnel")
public class StatisticalFunnelController {
    @Autowired
    private IStatisticsFunnelService statisticsFunnelService;
    @Autowired
    private IStatisticsFunnelFlowService statisticsFunnelFlowService;
    @Autowired
    private IStatisticsFunnelCountService iStatisticsFunnelCountService;
    @Autowired
    private IStatisticsEventService statisticsEventService;
    @Autowired
    private StatisticalFunnelBizService statisticalFunnelBizService;
    @Autowired
    private IMemberGroupService memberGroupService;

    Logger logger = LoggerFactory.getLogger(getClass());

    @RequestMapping("list")
    public ModelAndView list(StatisticsFunnel funnel, Page page, CommonInput input) {
        page.setLimit(10);
        ModelAndView mv = new ModelAndView("/analysis/funnelList");
        if (input.getTimeType() == null&&
                (StringUtils.isBlank(input.getCreateEnd())||StringUtils.isBlank(input.getCreateStart()))
                ){
            input.setTimeType(0);
        }
        Map<String, Object> params = CommonInput.appendParams(input);
        List<StatisticsFunnel> funnels = statisticsFunnelService.webListPage(funnel, params, page);
        for (StatisticsFunnel statisticsFunnel : funnels) {
            String flowNames = statisticsFunnel.getFlowNames();
            if (StringUtils.isNotEmpty(flowNames)) {
                flowNames = StringUtils.join(flowNames.split("\\|"), " > ");
                statisticsFunnel.setFlowNames(flowNames);
            }
        }
        if (null != params.get("startDate")) {
            input.setCreateStart(params.get("startDate").toString().substring(0, "2018-05-04".length()));
        }
        if (null != params.get("endDate")) {
            input.setCreateEnd(params.get("endDate").toString().substring(0, "2018-05-04".length()));
        }
        mv.addObject("funnel", funnel);
        mv.addObject("page", page);
        mv.addObject("input", input);
        mv.addObject("funnels", funnels);
        return mv;
    }


//    @RequestMapping("list")
//    public ModelAndView list(StatisticsFunnel funnel, Page page, CommonInput input) {
//        page.setLimit(10);
//        ModelAndView mv = new ModelAndView("/analysis/funnelList");
//        Map<String, Object> params = CommonInput.appendParams(input);
//        List<StatisticsFunnel> funnels = statisticsFunnelService.webListPage(funnel, params, page);
//        for (StatisticsFunnel statisticsFunnel : funnels) {
//            String flowNames = statisticsFunnel.getFlowNames();
//            if (StringUtils.isNotEmpty(flowNames)) {
//                flowNames = StringUtils.join(flowNames.split("\\|"), " > ");
//                statisticsFunnel.setFlowNames(flowNames);
//            }
//        }
//        if (null != params.get("startDate")) {
//            input.setCreateStart(params.get("startDate").toString().substring(0, "2018-05-04".length()));
//        }
//        if (null != params.get("endDate")) {
//            input.setCreateEnd(params.get("endDate").toString().substring(0, "2018-05-04".length()));
//        }
//        mv.addObject("funnel", funnel);
//        mv.addObject("page", page);
//        mv.addObject("input", input);
//        mv.addObject("funnels", funnels);
//        return mv;
//    }


    @RequestMapping("toForm")
    public ModelAndView toForm(String id) {
        ModelAndView mv = new ModelAndView("/analysis/funnelForm");
        List<StatisticsFunnelFlow> funnelFlows = Lists.newArrayList();
        if (StringUtils.isNotEmpty(id)) {
            StatisticsFunnel funnel = statisticsFunnelService.get(id);
            funnelFlows = statisticsFunnelFlowService.findByFunnelId(id);
            mv.addObject("funnel", funnel);

        } else {
            funnelFlows.add(new StatisticsFunnelFlow());
            funnelFlows.add(new StatisticsFunnelFlow());
            funnelFlows.add(new StatisticsFunnelFlow());
        }
        mv.addObject("funnelFlows", funnelFlows);
        List<StatisticsEvent> events = statisticsEventService.queryEventList();
        mv.addObject("events", events);
        return mv;
    }

    @ResponseBody
    @RequestMapping("save")
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public AjaxResult save(StatisticsFunnel funnel, String flowString) {
        if (StringUtils.isEmpty(flowString)) {
            return AjaxResult.error("流程不能为空");
        }
        try {
            List<Map> funnelFlows = JSONArray.parseArray(flowString, Map.class);
            if (funnelFlows.size() == 0) {
                return AjaxResult.error("流程节点不能为空");
            }
            if (StringUtils.isEmpty(funnel.getId())) {
                statisticsFunnelService.insert(funnel);
            } else {
                statisticsFunnelService.update(funnel);
            }

            statisticsFunnelFlowService.deleteByFunnelId(funnel.getId());
            for (Map funnelFlowMap : funnelFlows) {
                String eventId = funnelFlowMap.get("eventId").toString();
                Integer step = (Integer) funnelFlowMap.get("step");
                String flowName = funnelFlowMap.get("flowName").toString();

                StatisticsFunnelFlow funnelFlow = new StatisticsFunnelFlow();
                funnelFlow.setFunnelId(funnel.getId());
                funnelFlow.setEventId(eventId);
                funnelFlow.setStep(step);
                funnelFlow.setName(flowName);
                statisticsFunnelFlowService.insert(funnelFlow);
            }
            return AjaxResult.success();
        } catch (Exception e) {
            logger.error("保存漏斗异常", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("保存漏斗失败");
        }
    }

    @ResponseBody
    @RequestMapping("delete")
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public AjaxResult delete(String id) {
        if (StringUtils.isEmpty(id)) {
            return AjaxResult.error("漏斗编号不能为空");
        }
        try {
            statisticsFunnelFlowService.deleteByFunnelId(id);
            statisticsFunnelService.delete(id);
            return AjaxResult.success();
        } catch (Exception e) {
            logger.error("删除漏斗异常", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("删除漏斗失败");
        }
    }

    @RequestMapping("detail")
    public ModelAndView detail(String funnelId, CommonInput commonInput, String partnerId) {

        if (commonInput.getTimeType() == null&&
                (StringUtils.isBlank(commonInput.getCreateEnd())||StringUtils.isBlank(commonInput.getCreateStart()))
                ){
            commonInput.setTimeType(2);
        }

        CommonInput.transfromDate(commonInput);
        Map<String, Object> params = Maps.newHashMap();
        params.put("startDate", commonInput.getCreateStart());
        params.put("endDate", commonInput.getCreateEnd());
        params.put("partnerId", partnerId);
        params.put("funnelId", funnelId);

        if (StringUtils.isNotEmpty(commonInput.getCreateStart())) {
            commonInput.setCreateStart(commonInput.getCreateStart().substring(0, "2018-05-04".length()));
        }
        if (StringUtils.isNotEmpty(commonInput.getCreateEnd())) {
            commonInput.setCreateEnd(commonInput.getCreateEnd().substring(0, "2018-05-04".length()));
        }
        ModelAndView mv = new ModelAndView("/analysis/funnelDetail");
        List<String> flowNames = new LinkedList<>();
        List<Map<String, Object>> flowDatas = new LinkedList<>();
//        List<StatisticalFunnelOutput> funnelOutputs = statisticalFunnelBizService.webListPage(funnelId, flowNames, flowDatas, params);
        List<StatisticalFunnelOutput> funnelOutputs = statisticalFunnelBizService.webListPage2(flowDatas, params);
        mv.addObject("funnelOutputs", funnelOutputs);
        StatisticsFunnel statisticsFunnel = statisticsFunnelService.get(funnelId);
        mv.addObject("statisticsFunnel", statisticsFunnel);
        mv.addObject("flowNames", JSONObject.toJSONString(flowNames));
        mv.addObject("flowDatas", JSONObject.toJSONString(flowDatas));
        mv.addObject("input", commonInput);
        List<MemberGroup> partnerList = memberGroupService.getAllPartnerWithName();
        mv.addObject("partnerList", partnerList);
        mv.addObject("partnerId", partnerId);
        return mv;
    }
}
